Skip to content

Add --load-containing-class-only option #2633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

allredj
Copy link
Contributor

@allredj allredj commented Jul 30, 2018

Add option to only load the class (and inner classes) that contain the method under test.

Utility to search and replace strings inside a string.
@@ -38,7 +38,8 @@ Author: Daniel Kroening, [email protected]
"(java-max-input-tree-depth):" /* will go away */ \
"(max-nondet-tree-depth):" \
"(java-max-vla-length):" \
"(java-cp-include-files):" \
"(load-containing-class-only)" \
"(java-cp-include-files)" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing : (unless you really wanted to change the syntax here, which isn't reflected in the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo. Fixed.

@@ -59,6 +60,8 @@ Author: Daniel Kroening, [email protected]
" never initialize reference-typed parameter to the\n" /* NOLINT(*) */ \
" entry point with null\n" /* NOLINT(*) */ \
" --java-max-vla-length N limit the length of user-code-created arrays\n" /* NOLINT(*) */ \
" --load-containing-class-only only load the class containing the " \
" method under test and the library classes" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this differ from lazy loading? Obviously I'm not a Java expert, but as a mere user I'm pretty confused by this vast array of options.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lazy-loading will load all the classes that are needed to analyse the program. This option is more aggressive as it will cut out anything that leaves the class that contains the method under test. It's a wild over-approximation but it's an easy way of analysing blocks that would otherwise be intractable by jbmc.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, there is all the work that @hannes-steffenhagen-diffblue has done (7952f2c and related commits). Is doing it on a by-class level a much better approach for Java? Also, without your explanation above I would not have guess the semantics of this new option.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tautschnig The documentation is a bit sparse, I can easily agree with that. It's mostly the fault of the --help string format which we don't want to make to heavy. Where would a good place be to write an extended description?
At this point it's not clear how well a per-class approach would work. It's an experimental feature (I will document is as such).

Copy link
Member

@peterschrammel peterschrammel Jul 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is doing it on a by-class level a much better approach for Java?

Unfortunately, it's more complicated than that due to Java's compiler-generated methods, inner classes, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Near-duplicate of test-gen's single-function-only option? Perhaps both should be generalised into a function whitelist?

@@ -54,6 +54,7 @@ class optionst;
"(string-max-input-length):" \
"(aig)(16)(32)(64)(LP64)(ILP64)(LLP64)(ILP32)(LP32)" \
"(little-endian)(big-endian)" \
"(load-containing-class-only)" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being added to CBMC?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mistake. Will remove.

"javax\\/.*|"
"sun\\/.*|"
"org\\/cprover\\/.*|"
"com\\/diffblue\\/annotation\\/.*";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is obviously not great. Please suggest ways of making this more general.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not actually making it more general, but you might do (javax|sun|org\\/cprover|com\\/diffblue\\/annotation)\\/.*

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These hard-coded values make the option a bit misleading (it is not only loading the containing class). Maybe these could be added through java-cp-include-files as additional files to include (that have to be given explicitly) on the command line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romainbrenguier That might indeed be better. Will try that.

Add option to only load the class (and inner classes) that contain the
method under test.
@allredj allredj force-pushed the load-containing-class-only branch from 8c435e1 to caed4f9 Compare July 30, 2018 17:04
Copy link
Contributor Author

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passed Diffblue compatibility checks (cbmc commit: caed4f9).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/80402350

--
^warning: ignoring
--
Check that External.class is not loaded when using --load-containing-class-only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be good to have a test that shows the opposite is true without the option.

if(cmd.isset("java-cp-include-files"))
if(cmd.isset("load-containing-class-only"))
{
const std::string function_to_analyse = cmd.get_value("function");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes --function is set in the command line

if(first_dollar_index != std::string::npos)
class_name = class_name.substr(0, first_dollar_index);
else
class_name = class_name.substr(0, last_dot_index);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem to handle the case where there is no dot.

const std::size_t first_dollar_index =
function_to_analyse.find_first_of('$');
const std::size_t last_dot_index = function_to_analyse.find_last_of('.');
std::string class_name = function_to_analyse;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to copy function_to_analyse here, it can be used in the substr call instead.

"javax\\/.*|"
"sun\\/.*|"
"org\\/cprover\\/.*|"
"com\\/diffblue\\/annotation\\/.*";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These hard-coded values make the option a bit misleading (it is not only loading the containing class). Maybe these could be added through java-cp-include-files as additional files to include (that have to be given explicitly) on the command line.

@@ -67,4 +67,6 @@ Stream &join_strings(
/// programming language.
std::string escape(const std::string &);

void replace_all(std::string &, const std::string &, const std::string &);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping the name of the parameters could be nice.

@@ -148,3 +148,16 @@ std::string escape(const std::string &s)

return result;
}

void replace_all(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation would be nice.

const std::string &to)
{
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A for-loop maybe clearer.

if(first_dollar_index != std::string::npos)
class_name = class_name.substr(0, first_dollar_index);
else
class_name = class_name.substr(0, last_dot_index);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There always should be one in a Java function ID (but make an INVARIANT)

replace_all(class_name, ".", "\\/");
java_cp_include_files = class_name +
"(\\$.*)?\\.class|"
"java\\/.*|"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think / needs escaping?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loading all inner classes is a bit weird, should they only be inners of the desired class?

regex_matcher=std::regex(java_cp_include_files);
debug() << "Limit loading to classes matching : " << java_cp_include_files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class-loading is limited to...

@allredj allredj mentioned this pull request Jul 31, 2018
@allredj
Copy link
Contributor Author

allredj commented Jul 31, 2018

Moving the core functionality out of jbmc as it is not very relevant to verification. Replacement PR: #2640

@allredj allredj closed this Jul 31, 2018
@allredj allredj deleted the load-containing-class-only branch July 31, 2018 10:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants